local hex = require 'util.hex'
local base64 = require 'util.base64'
local base64_encode = base64.encode
local base64_decode = base64.decode

local mt = {}
mt.__index = mt

local function copyTable(t)
    local r = {}
    for k,v in pairs(t) do 
        if type(v) == 'table' then 
            r[k] = copyTable(t[k])
        else
            r[k] = v
        end 
    end
    return r
end

function mt:default()
    return copyTable(self._default)
end 

function mt:encode(tbl)
    local ok, res = pcall(self._define.encode, self._define, tbl)
    if not ok or not res then 
        return ""
    end 
    local ok, res = pcall(base64_encode, res)
    if not ok or not res then 
        return ""
    end 
    return res 
end 

function mt:decode(buf)
    local ok, res = pcall(base64_decode, buf)
    if not ok or not res then 
        return self:default()
    end 
    local ok, res = pcall(self._define.decode, self._define, res)
    if not ok or not res then 
        return self:default()
    end 
    return res
end

local export = {}

function export.new(define, default)
    return setmetatable({
        _define = hex.define(define),
        _default = default,
    }, mt) 
end 

return export

